//
//  StringExtension.swift
//  DemoNavBar
//
//  Created by YangHuan on 2019/12/13.
//  Copyright © 2019 YangHuan. All rights reserved.
//

import Foundation
import UIKit


public func LString(str: String)->String {
    
    return InternationalControl.string(str: str)
}


extension String {
    public subscript(_ range: CountableRange<Int>) -> String? {
        guard let lowerIndex = index(startIndex, offsetBy: max(0, range.lowerBound), limitedBy: endIndex) else { return nil }
        guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) else { return nil }
        return String(self[lowerIndex..<upperIndex])
    }
    
    public subscript(safe i: Int) -> Character? {
        guard i >= 0 && i < count else { return nil }
        return self[index(startIndex, offsetBy: i)]
    }
}

extension String {
    public func subString(from: Int?, to: Int?) -> String {
        if let start = from {
            guard start < self.count else {
                return ""
            }
        }
        
        if let end = to {
            guard end >= 0 else {
                return ""
            }
        }
        
        if let start = from, let end = to {
            guard end - start >= 0 else {
                return ""
            }
        }
        
        let startIndex: String.Index
        if let start = from, start >= 0 {
            startIndex = self.index(self.startIndex, offsetBy: start)
        } else {
            startIndex = self.startIndex
        }
        
        let endIndex: String.Index
        if let end = to, end >= 0, end < self.count {
            endIndex = self.index(self.startIndex, offsetBy: end + 1)
        } else {
            endIndex = self.endIndex
        }
        
        return String(self[startIndex ..< endIndex])
    }
    
    func subString(from: Int) -> String {
        return self.subString(from: from, to: nil)
    }
    
    func subString(to: Int) -> String {
        return self.subString(from: nil, to: to)
    }
    
    func subString(from: Int?, length: Int) -> String {
        guard length > 0 else {
            return ""
        }
        
        let end: Int
        if let start = from, start > 0 {
            end = start + length - 1
        } else {
            end = length - 1
        }
        
        return self.subString(from: from, to: end)
    }
    
    func subString(length: Int, to: Int?) -> String {
        guard let end = to, end > 0, length > 0 else {
            return ""
        }
        
        let start: Int
        if let end = to, end - length > 0 {
            start = end - length + 1
        } else {
            start = 0
        }
        
        return self.subString(from: start, to: to)
    }
}
extension String {
    
    func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
        return ceil(boundingBox.height)
    }
    
    func width(withConstraintedHeight height: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
        
        return ceil(boundingBox.width)
    }
}

// MARK: - 小数点处理
extension String {
    enum DecimalRegex: String {
        /// 小数点后五位
        case four = "^[0-9]*((\\.|,)[0-9]{0,4})?$"
        case five = "^[0-9]*((\\.|,)[0-9]{0,5})?$"
    }
    
    
    
    func judgeWith(_ regex: DecimalRegex) -> Bool {
        let regex = try! NSRegularExpression(pattern: regex.rawValue, options: NSRegularExpression.Options.allowCommentsAndWhitespace)
        let numberOfMatches = regex.numberOfMatches(in: self, options:NSRegularExpression.MatchingOptions.reportProgress, range: NSMakeRange(0, (self as NSString).length))
        return numberOfMatches != 0
    }

}

extension String {
    public func subCNString(from index: Int) -> String? {
        if self.count > index {
            let startIndex = self.index(self.startIndex, offsetBy: index)
            let subString = self[startIndex...]
            return String(subString)
        } else {
            return nil
        }
    }
    public func subCNString(to index: Int) -> String? {
        if self.count > index {
            let sIndex = self.index(self.startIndex, offsetBy: index)
            let subindex = self.index(before: sIndex)
            let subString = self[startIndex...subindex]
            return String(subString)
        } else {
            return nil
        }
    }
}

// MARK: - 随机用户名生成
extension String {
    
    /// 随机生成含有字母和数字的字符串
    ///
    /// - Parameter length: 字符串长度
    /// - Returns: 字符串
    public static func random(length: Int = 10) -> String {
        return String(randomWithLength: length, allowedCharactersType: .alphaNumeric)
    }
    
    public init(randomWithLength length: Int, allowedCharactersType: AllowedCharacters) {
        let allowedCharsString: String = {
            switch allowedCharactersType {
            case .numeric:
                return "0123456789"
                
            case .alphabetic:
                return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
                
            case .alphaNumeric:
                return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
            case .allCharactersIn(let allowedCharactersString):
                return allowedCharactersString
            }
        }()
        
        self.init(allowedCharsString.sample(size: length)!)
    }
    
    public var isBlank: Bool { return stripped().isEmpty }
    
    public func stripped() -> String { return trimmingCharacters(in: .whitespacesAndNewlines) }
    

    public var sample: Character? {
        return isEmpty ? nil : self[index(startIndex, offsetBy: Int.random(in: 0..<count))]
    }
    
    public func sample(size: Int) -> String? {
        guard !isEmpty else { return nil }
        
        var sampleElements = String()
        
        for _ in 0..<size {
            sampleElements.append(sample!)
        }
        return sampleElements
    }
    
    public enum AllowedCharacters {
        case numeric
        case alphabetic
        case alphaNumeric
        case allCharactersIn(String)
    }
}


extension String {
    var intValue: Int? {
        return Int(self)
    }
}
